package br.com.usapre.faces;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import br.com.business.DescontoParceiroBusiness;
import br.com.business.GradeProdutosBusiness;
import br.com.business.GrupoProdutosBusiness;
import br.com.business.NoticiasBusiness;
import br.com.business.SubGrupoProdutosBusiness;
import br.com.business.TipoNoticiaBusiness;
import br.com.data.DescontoParceiro;
import br.com.data.GradeProdutos;
import br.com.data.GrupoProdutos;
import br.com.data.Noticias;
import br.com.data.Parceiro;
import br.com.data.Produtos;
import br.com.data.SubGrupoProdutos;
import br.com.login.faces.SessionUsaPreBean;
import br.com.utilidades.database.data.Criterio;
import br.com.utilidades.faces.SimpleMessageBean;

/**
 * @version 1.0.0
 * @since Fevereiro,28 2013
 * @author Eduardo Francisco Barbosa
 */
@Component
@Scope("session")
public class LojistaGerenciamentoCadastroPrecos extends SimpleMessageBean implements Serializable {

    private static final long serialVersionUID = 6869078992597848525L;

    private SessionUsaPreBean sessionUsaPreBean;

    private GrupoProdutosBusiness grupoProdutosBusinessImpl;
    private SubGrupoProdutosBusiness subGrupoProdutosBusinessImpl;
    private GradeProdutosBusiness gradeProdutosBusinessImpl;

    private DescontoParceiroBusiness descontoParceiroBusiness;
    private NoticiasBusiness noticiaBusiness;
    private TipoNoticiaBusiness tipoNoticiaBusiness;

    private Parceiro parceiro;

    private List<GrupoProdutos> gruposProdutos;
    private GrupoProdutos grupoEscolhido;

    private List<SubGrupoProdutos> subGrupoProdutos;
    private SubGrupoProdutos subGrupoEscolhido;

    private String nomeProduto;

    private List<GradeProdutos> gradeProdutos;
    private GradeProdutos gradeProdutoSelecionado;

    List<GradeProdutos> historico;

    private DescontoParceiro descontoParceiro;

    private Integer tela;

    private Boolean liberadoInsercao;

    private Double valorDesconto;

    public static final Integer TELA_VISUALIZACAO = 1;
    public static final Integer TELA_EDITAR = 2;
    public static final Integer TELA_HISTORICO = 3;

    /**
     * Construtor
     */
    @Autowired
    public LojistaGerenciamentoCadastroPrecos(SessionUsaPreBean sessionUsaPreBean,
	    GrupoProdutosBusiness grupoProdutosBusinessImpl, SubGrupoProdutosBusiness subGrupoProdutosBusinessImpl,
	    GradeProdutosBusiness gradeProdutosBusinessImpl, DescontoParceiroBusiness descontoParceiroBusiness,
	    NoticiasBusiness noticiaBusiness, TipoNoticiaBusiness tipoNoticiaBusiness) {

	this.sessionUsaPreBean = sessionUsaPreBean;

	this.gradeProdutosBusinessImpl = gradeProdutosBusinessImpl;
	this.grupoProdutosBusinessImpl = grupoProdutosBusinessImpl;
	this.subGrupoProdutosBusinessImpl = subGrupoProdutosBusinessImpl;

	this.descontoParceiroBusiness = descontoParceiroBusiness;
	this.noticiaBusiness = noticiaBusiness;
	this.tipoNoticiaBusiness = tipoNoticiaBusiness;

	parceiro = this.sessionUsaPreBean.getParceiro();

	reset();
    }

    /**
     * reset
     */
    public void reset() {

	liberadoInsercao = Boolean.FALSE;

	if (parceiro == null) {
	} else {

	    List<Criterio> criterios = new ArrayList<Criterio>();

	    Criterio crit01 = new Criterio();
	    crit01.setCampo("parceiro.id");
	    crit01.setComparacao("=");
	    crit01.setTipo(Criterio.TIPO_INTEGER);
	    crit01.setValue(parceiro.getId());

	    criterios.add(crit01);

	    List<DescontoParceiro> descontos = descontoParceiroBusiness.buscarPorCriterios(criterios, "data DESC ", 1);

	    if (descontos.size() == 0) {
		descontoParceiro = new DescontoParceiro();
	    } else {
		descontoParceiro = descontos.get(0);
	    }

	}

	tela = TELA_VISUALIZACAO;

	List<Criterio> criterios = new ArrayList<Criterio>();

	Criterio criterio = new Criterio();

	criterio.setCampo("ramoAtividade.id");
	criterio.setComparacao("=");
	criterio.setTipo(Criterio.TIPO_INTEGER);
	criterio.setValue(parceiro.getRamoAtividade().getId());

	criterios.add(criterio);

	gruposProdutos = grupoProdutosBusinessImpl.buscarPorCriterios(criterios, "nome");

	nomeProduto = "";

	gradeProdutos = new ArrayList<GradeProdutos>();

	buscarPrecos();

    }

    /**
     * atualizarSubGrupos
     */
    public void atualizarSubGrupos() {

	if (grupoEscolhido == null || grupoEscolhido.getId() == 0) {

	    subGrupoProdutos = new ArrayList<SubGrupoProdutos>();

	} else {

	    List<Criterio> criterios = new ArrayList<Criterio>();

	    Criterio criterio = new Criterio();

	    criterio.setCampo("grupoProdutos.id");
	    criterio.setComparacao("=");
	    criterio.setTipo(Criterio.TIPO_INTEGER);
	    criterio.setValue(grupoEscolhido.getId());

	    criterios.add(criterio);

	    subGrupoProdutos = subGrupoProdutosBusinessImpl.buscarPorCriterios(criterios, "");

	}

    }

    /**
     * buscarPrecos
     */
    public void buscarPrecos() {

	gradeProdutos = gradeProdutosBusinessImpl.buscarGradeProdutosPorParceiro(subGrupoEscolhido, grupoEscolhido,
		parceiro.getRamoAtividade(), nomeProduto, parceiro);

    }

    /**
     * marcarTodos
     */
    public void marcarTodos() {

	for (GradeProdutos gp : gradeProdutos) {

	    if (gp.getSelecionado() != null && gp.getSelecionado().equals(Boolean.TRUE)) {
		gp.setSelecionado(Boolean.FALSE);
	    } else {
		gp.setSelecionado(Boolean.TRUE);
	    }
	}

    }

    /**
     * alterarDesconto
     */
    public void alterarDesconto() {
	for (GradeProdutos gp : gradeProdutos) {
	    if (gp.getSelecionado() != null && gp.getSelecionado().equals(Boolean.TRUE)) {

		Double percentualDesconto = (gp.getValor() - (gp.getValor() * valorDesconto / 100));

		gp.setDesconto(valorDesconto);
		gp.setPreco(percentualDesconto);
		this.gradeProdutosBusinessImpl.salvar(gp);
	    }
	}
    }

    /**
     * editarProduto
     */
    public void editarProduto() {

	tela = TELA_EDITAR;

    }

    /**
     * visualizarAlteracao
     */
    public void visualizarAlteracao() {

	tela = TELA_HISTORICO;

	List<Criterio> crit = new ArrayList<Criterio>();

	Criterio criterio = new Criterio();

	criterio.setCampo("produtos.id");
	criterio.setComparacao("=");
	criterio.setTipo(Criterio.TIPO_INTEGER);
	criterio.setValue(gradeProdutoSelecionado.getProdutos().getId());

	crit.add(criterio);

	criterio = new Criterio();

	criterio.setCampo("parceiro.id");
	criterio.setComparacao("=");
	criterio.setTipo(Criterio.TIPO_INTEGER);
	criterio.setValue(parceiro.getId());

	crit.add(criterio);

	historico = gradeProdutosBusinessImpl.buscarPorCriterios(crit, "id desc");

	int a = 0;
	for (GradeProdutos gp : historico) {
	    if (a == 0) {
		a = 1;
		gp.setImpar(Boolean.FALSE);
	    } else {
		a = 0;
		gp.setImpar(Boolean.TRUE);
	    }
	}

    }

    /**
     * cadastrarNovoPreco
     */
    public void cadastrarNovoPreco() {

	if (liberadoInsercao) {
	    if (gradeProdutoSelecionado.getDataFim().after(gradeProdutoSelecionado.getDataInicio())) {

		GradeProdutos gp = new GradeProdutos();

		GradeProdutos gpS = gradeProdutoSelecionado;

		gp.setDataDia(new Date());
		gp.setDataFim(gpS.getDataFim());
		gp.setDataInicio(gpS.getDataInicio());
		gp.setDesconto(gpS.getDesconto());
		gp.setPreco(gpS.getPreco());
		gp.setProdutos(gpS.getProdutos());
		gp.setQtdadeMaxima(gpS.getQtdadeMaxima());
		gp.setParceiro(parceiro);
		gp.setValor(gpS.getValor());

		gradeProdutosBusinessImpl.salvar(gp);

		deletarNoticiasRepetidas(gpS.getProdutos());

		Noticias newNoticia = new Noticias();

		newNoticia.setTipoNoticia(tipoNoticiaBusiness.buscarPorId(1));
		newNoticia.setDataCadastro(new Date());
		newNoticia.setDataInicial(gpS.getDataInicio());
		newNoticia.setDataFinal(gpS.getDataFim());
		newNoticia.setParceiro(parceiro);
		newNoticia.setProdutos(gpS.getProdutos());
		newNoticia.setStatus(Boolean.TRUE);

		newNoticia.setDado1(gpS.getProdutos().getNome());
		newNoticia.setDado2(gpS.getProdutos().getUnidade());

		newNoticia.setDado5(gpS.getPreco());
		newNoticia.setDado6(gpS.getDesconto());

		noticiaBusiness.salvar(newNoticia);

		tela = TELA_VISUALIZACAO;

		buscarPrecos();
	    } else {
		String msg = super.getMensagem("MN_data_final_maior_inicio");
		enviaMensagemErro(msg, msg);
	    }
	} else {
	    String msg = super.getMensagem("MN_valores_precos_incorretos");
	    enviaMensagemErro(msg, msg);
	}

    }

    private void deletarNoticiasRepetidas(Produtos produtos) {
	List<Criterio> criterios = new ArrayList<Criterio>();

	Criterio crit = new Criterio();
	crit.setCampo("parceiro.id");
	crit.setComparacao("=");
	crit.setTipo(Criterio.TIPO_INTEGER);
	crit.setValue(parceiro.getId());

	criterios.add(crit);

	crit = new Criterio();
	crit.setCampo("produtos");
	crit.setComparacao("=");
	crit.setTipo(Criterio.TIPO_INTEGER);
	crit.setValue(produtos.getId());

	criterios.add(crit);

	List<Noticias> noticias = noticiaBusiness.buscarPorCriterios(criterios, "");
	for (Noticias not : noticias) {
	    not.setStatus(Boolean.FALSE);
	    noticiaBusiness.atualizar(not);
	}
    }

    /**
     * voltar
     */
    public void voltar() {

	buscarPrecos();

	tela = TELA_VISUALIZACAO;

    }

    /**
     * atualizaPrecoNormal
     */
    public void atualizaPrecoNormal() {

	Double percentual = gradeProdutoSelecionado.getDesconto();
	Double percentualValido = 1d;
	percentualValido = percentualValido - percentual / 100;

	Double valorPreco = gradeProdutoSelecionado.getValor() * percentualValido;

	gradeProdutoSelecionado.setPreco(valorPreco);
	liberadoInsercao = Boolean.TRUE;

    }

    /**
     * atualizaPrecoFinal
     */
    public void atualizaPrecoFinal() {

	Double valorProduto = gradeProdutoSelecionado.getValor();
	Double percentual = gradeProdutoSelecionado.getDesconto();

	Double percentualValido = 1d;

	if (percentual > 0) {
	    percentualValido = percentualValido - percentual / 100;
	    Double valorPreco = valorProduto * percentualValido;
	    gradeProdutoSelecionado.setPreco(valorPreco);
	    liberadoInsercao = Boolean.TRUE;
	}

	if (percentual < 0) {
	    enviaMensagemErro("O campo de desconto deve ser um valor positivo",
		    "O campo de desconto deve ser um valor positivo");
	    liberadoInsercao = Boolean.FALSE;
	}

    }

    /**
     * atualizaPercentualDesconto
     */
    public void atualizaPercentualDesconto() {

	Double valorProduto = gradeProdutoSelecionado.getValor();
	Double valorPreco = gradeProdutoSelecionado.getPreco();

	Double percentualValido = 1d;

	if (valorPreco < valorProduto) {
	    percentualValido = valorPreco / valorProduto;
	    Double percentual = (1 - percentualValido) * 100;
	    gradeProdutoSelecionado.setDesconto(percentual);
	    liberadoInsercao = Boolean.TRUE;
	}
	if (valorPreco > valorProduto) {
	    enviaMensagemErro("O valor do preço com desconto deve ser menor que o preço normal",
		    "O valor do preço com desconto deve ser menor que o preço normal");
	    liberadoInsercao = Boolean.FALSE;
	}

    }

    public boolean isTelaVisualizar() {
	if (tela.equals(TELA_VISUALIZACAO))
	    return Boolean.TRUE;
	else
	    return Boolean.FALSE;
    }

    public boolean isTelaEditar() {
	if (tela.equals(TELA_EDITAR))
	    return Boolean.TRUE;
	else
	    return Boolean.FALSE;
    }

    public boolean isTelaHistorico() {
	if (tela.equals(TELA_HISTORICO))
	    return Boolean.TRUE;
	else
	    return Boolean.FALSE;
    }

    // SETS AND GETS
    public Parceiro getParceiro() {
	return parceiro;
    }

    public void setParceiro(Parceiro parceiro) {
	this.parceiro = parceiro;
    }

    public List<GrupoProdutos> getGruposProdutos() {
	return gruposProdutos;
    }

    public void setGruposProdutos(List<GrupoProdutos> gruposProdutos) {
	this.gruposProdutos = gruposProdutos;
    }

    public GrupoProdutos getGrupoEscolhido() {
	return grupoEscolhido;
    }

    public void setGrupoEscolhido(GrupoProdutos grupoEscolhido) {
	this.grupoEscolhido = grupoEscolhido;
    }

    public List<SubGrupoProdutos> getSubGrupoProdutos() {
	return subGrupoProdutos;
    }

    public void setSubGrupoProdutos(List<SubGrupoProdutos> subGrupoProdutos) {
	this.subGrupoProdutos = subGrupoProdutos;
    }

    public SubGrupoProdutos getSubGrupoEscolhido() {
	return subGrupoEscolhido;
    }

    public void setSubGrupoEscolhido(SubGrupoProdutos subGrupoEscolhido) {
	this.subGrupoEscolhido = subGrupoEscolhido;
    }

    public String getNomeProduto() {
	return nomeProduto;
    }

    public void setNomeProduto(String nomeProduto) {
	this.nomeProduto = nomeProduto;
    }

    public GradeProdutosBusiness getGradeProdutosBusinessImpl() {
	return gradeProdutosBusinessImpl;
    }

    public void setGradeProdutosBusinessImpl(GradeProdutosBusiness gradeProdutosBusinessImpl) {
	this.gradeProdutosBusinessImpl = gradeProdutosBusinessImpl;
    }

    public Integer getTela() {
	return tela;
    }

    public void setTela(Integer tela) {
	this.tela = tela;
    }

    public List<GradeProdutos> getHistorico() {
	return historico;
    }

    public void setHistorico(List<GradeProdutos> historico) {
	this.historico = historico;
    }

    public DescontoParceiro getDescontoParceiro() {
	return descontoParceiro;
    }

    public void setDescontoParceiro(DescontoParceiro descontoParceiro) {
	this.descontoParceiro = descontoParceiro;
    }

    public List<GradeProdutos> getGradeProdutos() {
	return gradeProdutos;
    }

    public void setGradeProdutos(List<GradeProdutos> gradeProdutos) {
	this.gradeProdutos = gradeProdutos;
    }

    public GradeProdutos getGradeProdutoSelecionado() {
	return gradeProdutoSelecionado;
    }

    public void setGradeProdutoSelecionado(GradeProdutos gradeProdutoSelecionado) {
	this.gradeProdutoSelecionado = gradeProdutoSelecionado;
    }

    /**
     * Retorna o valor do atributo valorDesconto.
     * 
     * @return valorDesconto
     */
    public Double getValorDesconto() {

	return valorDesconto;
    }

    /**
     * Define o valor do atributo valorDesconto.
     * 
     * @param valorDesconto
     *            valor a ser atribuído
     */
    public void setValorDesconto(Double valorDesconto) {

	this.valorDesconto = valorDesconto;
    }

}
